package mh.map;

import java.io.IOException;

import mh.GameWindow;
import mh.interfaces.IImage;

import org.lwjgl.opengl.GL11;

/**
 * This class create a new animated sprite the uses a <code>Texture</code> that contains each frame of the animation.<br>
 * The animation is a matrix of frames 3x5, each line contains a direction, each row one of the subsequential steps of
 * the movement.<br>
 * 
 * @author Gianmarco Laggia
 * 
 */
public class Sprite implements IImage {
	/** The texture that stores the image for this sprite (not just one frame) */
	private Texture	texture;

	/** The row of the fram to be printed. giu sx dx su */
	private int		direction;

	/** The frame that will be painted */
	private int		frame	= 0;

	/**
	 * Create a new animated sprite from a specified image.
	 * 
	 * @param window
	 *            The window in which the sprite will be displayed
	 * @param ref
	 *            A reference to the image on which this sprite should be based
	 */
	public Sprite(GameWindow window, String ref) {
		try {
			this.texture = TextureLoader.getTexture(ref, true, null);

			// this.width = this.texture.getImageWidth();
			// this.height = this.texture.getImageHeight();
		} catch (IOException e) {
			// a tad abrupt, but our purposes if you can't find a
			// sprite's image you might as well give up.
			System.err.println("Unable to load texture: " + ref);
			System.exit(0);
		}
	}

	/**
	 * 
	 * @param d
	 */
	@Override
	public void setDirection(int d) {
		this.direction = d;
	}

	@Override
	public void frameUp() {
		this.frame++;
		if (this.frame > 2) {
			this.frame = 0;
		}
	}

	/**
	 * 
	 * @param f
	 */
	@Override
	public void setFrame(int f) {
		if ((f > 2) || (f < 0)) {
			this.frame = 0;
		} else {
			this.frame = f;
		}
	}

	/**
	 * Get the width of this sprite in pixels
	 * 
	 * @return The width of this sprite in pixels
	 */
	@Override
	public int getWidth() {
		return this.texture.getImageWidth();
	}

	/**
	 * Get the height of this sprite in pixels
	 * 
	 * @return The height of this sprite in pixels
	 */
	@Override
	public int getHeight() {
		return this.texture.getImageHeight();
	}

	/**
	 * Draw the sprite at the specified location
	 * 
	 * @param x
	 *            The x location where to draw this sprite
	 * @param y
	 *            The y location where to draw this sprite
	 */
	@Override
	public void draw(double x, double y) {
		// store the current model matrix
		GL11.glPushMatrix();

		// bind to the appropriate texture for this sprite
		this.texture.bind();

		// translate to the right location and prepare to draw
		GL11.glTranslated(x, y, 0);
		GL11.glColor3f(1, 1, 1);
		// draw a quad textured to match the sprite
		GL11.glBegin(GL11.GL_QUADS);
		{
			// 0.90625
			GL11.glTexCoord2d((this.frame * this.texture.getWidth()) / 12, (this.direction * this.texture.getHeight()) / 8);
			GL11.glVertex2d(0, 0);
			GL11.glTexCoord2d((this.frame * this.texture.getWidth()) / 12, ((this.direction + 1) * this.texture.getHeight()) / 8);
			GL11.glVertex2d(0, 32); // 384:32 = 0.75:?
			GL11.glTexCoord2d(((this.frame + 1) * this.texture.getWidth()) / 12d, ((this.direction + 1) * this.texture.getHeight()) / 8);
			GL11.glVertex2d(32, 32);
			GL11.glTexCoord2d(((this.frame + 1) * this.texture.getWidth()) / 12d, (this.direction * this.texture.getHeight()) / 8);
			GL11.glVertex2d(32, 0);
			// GL11.glTexCoord2f(0, 0);
			// GL11.glVertex2f(0, 0);
			// GL11.glTexCoord2f(0, this.texture.getHeight());
			// GL11.glVertex2f(0, this.height);
			// GL11.glTexCoord2f(this.texture.getWidth(), this.texture.getHeight());
			// GL11.glVertex2f(this.width,this.height);
			// GL11.glTexCoord2f(this.texture.getWidth(), 0);
			// GL11.glVertex2f(this.width,0);
		}
		GL11.glEnd();

		// restore the model view matrix to prevent contamination
		GL11.glPopMatrix();
	}

}
